import { Component, Enum, Node, UITransform, Vec3, _decorator } from 'cc';
const { ccclass, property, executeInEditMode } = _decorator;

export const MatchMode = Enum({
    None: 0,
    FitWidth: 1,
    FitHeight: 2,
    ShowAll: 3,
    NoBoard: 4,
})

@ccclass('UIScaler')
@executeInEditMode
export default class UIScaler extends Component {
    @property({
        type: MatchMode,
        tooltip: "缩放方式"
    })
    matchMode = MatchMode.None;

    _thisTransform: UITransform;

    protected onLoad(): void {
        this._thisTransform = this.node.getComponent(UITransform);
    }

    protected onEnable(): void {
        this.node.on(Node.EventType.PARENT_CHANGED, this.onParentChanged, this);
        const parent = this.node.parent;
        if (parent)
        {
            parent.on(Node.EventType.SIZE_CHANGED, this.onParentSizeChanged, this);
        }
        this.onParentSizeChanged();
    }

    protected onDisable(): void {
        this.node.off(Node.EventType.PARENT_CHANGED, this.onParentChanged, this);
        const parent = this.node.parent;
        if (parent)
        {
            parent.off(Node.EventType.SIZE_CHANGED, this.onParentSizeChanged, this);
        }
    }

    private onParentChanged(): void
    {
        console.error(`Dont change node with UIScaler:${this.node} parent when its active, this will cause a leack error`);
    }

    onFocusInEditor(): void {
        this.onParentSizeChanged();
    }

    private onParentSizeChanged(): void
    {
        const parent: Node = this.node.parent;
        const parentTransform: UITransform = parent?.getComponent(UITransform);
        if (!parentTransform)
            return;

        switch (this.matchMode) {
            case MatchMode.FitWidth:{
                const scale: number = parentTransform.width / this._thisTransform.width;
                this.node.setScale(new Vec3(scale, scale, scale));
                break;
            }
            case MatchMode.FitHeight:{
                const scale: number = parentTransform.height / this._thisTransform.height;
                this.node.setScale(new Vec3(scale, scale, scale));
                break;
            }
            case MatchMode.ShowAll:{
                const scaleWidth: number = parentTransform.width / this._thisTransform.width;
                const scaleHeight: number = parentTransform.height / this._thisTransform.height;
                const scale: number = Math.min(scaleWidth, scaleHeight);
                this.node.setScale(new Vec3(scale, scale, scale));
                break;
            }
            case MatchMode.NoBoard:{
                const scaleWidth: number = parentTransform.width / this._thisTransform.width;
                const scaleHeight: number = parentTransform.height / this._thisTransform.height;
                const scale: number = Math.max(scaleWidth, scaleHeight);
                this.node.setScale(new Vec3(scale, scale, scale));
                break;
            }
            default:
                this.node.setScale(new Vec3(1, 1, 1));
                break;
        }
    }
}